using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Library.WebControls.SimpleSpinEdit {
	[ToolboxBitmap(typeof(SpSpinEdit), "Library.WebControls.SimpleSpinEdit.include.SpPpinEdit.bmp")]
	[Designer(typeof(SpSpinEditDesign))]
	[SupportsEventValidation]
	[ToolboxData("<{0}:SpSpinEdit runat=server></{0}:SpSpinEdit>")]
	[DesignTimeVisible(true)]
	public class SpSpinEdit : BaseControl {
		public const string NegativeSignal = "-";
		protected Type SpSpinEditType = typeof(SpSpinEdit);
		private string _notAnumberText = String.Empty;
		private string _numberDecimalSeparator;
		private string _numberGroupSeparator;
		private TextBox _textBox;

		private HtmlGenericControl _divContainer;

		public SpSpinEdit() {
			CssFileName = BaseCssDir + "spspinedit-ui.css";
		}

		public override string ID {
			get {
				EnsureChildControls();
				return _textBox.ID;
			}
			set {
				EnsureChildControls();
				_textBox.ID = value;
			}
		}

		public override string ClientID {
			get {
				EnsureChildControls();
				return _textBox.ClientID;
			}
		}

		public override string UniqueID {
			get { return _textBox.UniqueID; }
		}

		public Unit Width {
			get {
				EnsureChildControls();
				return new Unit(_divContainer.Style[HtmlTextWriterStyle.Width]);
			}
			set {
				EnsureChildControls();
				_divContainer.Style[HtmlTextWriterStyle.Width] = value.ToString();
			}
		}

		public FontInfo Font {
			get {
				EnsureChildControls();
				return _textBox.Font;
			}
		}

		public Color ForeColor {
			get {
				EnsureChildControls();
				return _textBox.ForeColor;
			}
			set {
				EnsureChildControls();
				_textBox.ForeColor = value;
			}
		}


		public override bool ClientEnable {
			get {
				EnsureChildControls();
				return !_textBox.ReadOnly;
			}
			set {
				EnsureChildControls();
				_textBox.ReadOnly = !value;
			}
		}

		public override bool ClientVisible {
			get {
				EnsureChildControls();
				return _divContainer.Style[HtmlTextWriterStyle.Display] != "none";
			}
			set {
				if (value) {
					_divContainer.Style.Remove(HtmlTextWriterStyle.Display);
				} else {
					_divContainer.Style[HtmlTextWriterStyle.Display] = "none";
				}
			}
		}





		public SpSpinEditStyle NumberStyle { get; set; }

		public string NumberDecimalSeparator {
			get {
				if (String.IsNullOrEmpty(_numberDecimalSeparator)) {
					try {
						_numberDecimalSeparator = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
					} catch {
						_numberDecimalSeparator = ",";
					}
				}
				return _numberDecimalSeparator;
			}
			set {
				Check(value, "NumberDecimalSeparator");
				_numberDecimalSeparator = value;
				BuilderText();
			}
		}

		public string NumberGroupSeparator {
			get {
				if (String.IsNullOrEmpty(_numberGroupSeparator)) {
					try {
						_numberGroupSeparator = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator;
					} catch {
						_numberGroupSeparator = ".";
					}
				}
				return _numberGroupSeparator;
			}
			set {
				Check(value, "NumberGroupSeparator");
				_numberGroupSeparator = value;
				BuilderText();
			}
		}

		public string NotAnumberText {
			get { return _notAnumberText; }
			set { _notAnumberText = value; }
		}

		//public int IntNumber {
		//  get { return 0; }
		//}
		//public float FloatNumber {
		//  get { return 0; }
		//}
		internal int ParseInt(string text) {
			return Int32.Parse(text.Replace(NumberGroupSeparator,
																			Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator));
		}

		internal double ParseFloat(string text) {
			text = text.Replace(NumberGroupSeparator,
																								 Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator);
			text = text.Replace(NumberDecimalSeparator,
													Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
			return double.Parse(text);
		}
		public double Number {
			get {
				//return 10;
				EnsureChildControls();

				try {
					switch (NumberStyle) {
						case SpSpinEditStyle.Float:
							return ParseFloat(_textBox.Text);
						case SpSpinEditStyle.Integer:
							return ParseInt(_textBox.Text);
					}
				} catch {
					return 0;
				}
				return 0;
			}
			set {
				EnsureChildControls();
				try {
					switch (NumberStyle) {
						case SpSpinEditStyle.Float:
							_textBox.Text =
								value.ToString("F").Replace(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator,
																						NumberGroupSeparator).Replace(
																							Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator,
																							NumberDecimalSeparator);
							break;
						case SpSpinEditStyle.Integer:
							string t = value.ToString("N0");
							_textBox.Text = t.Replace(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator,
																			 NumberGroupSeparator);
							break;
					}
				} catch {
				}
			}
		}

		public string Text {
			get {
				EnsureChildControls();
				return _textBox.Text;
			}
		}

		internal TextBox TextEdit {
			get {
				EnsureChildControls();
				return _textBox;
			}
		}

		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);
			IncludeScriptOnLoad(SpSpinEditType, "SPSpinEdit", "Library.WebControls.SimpleSpinEdit.include.SpSpinEdit.js");
		}

		protected override void CreateChildControls() {
			_divContainer = new HtmlGenericControl("div");
			var div = new HtmlGenericControl("div");
			_divContainer.Attributes["class"] = "speEditor";
			_textBox = new TextBox { TextMode = TextBoxMode.SingleLine };
			_textBox.BorderStyle = BorderStyle.None;
			_textBox.BorderWidth = new Unit(0);
			_textBox.Width = new Unit("100%");
			_textBox.BorderColor = Color.Transparent;
			div.Controls.Add(_textBox);
			_divContainer.Controls.Add(div);
			Controls.Add(_divContainer);
		}

		private static void Check(string n, string error) {
			if (String.IsNullOrEmpty(n) || n == NegativeSignal) {
				throw new ArgumentNullException(error);
			}
			if (n.Any(Char.IsNumber)) {
				throw new ArgumentNullException(error);
			}
		}

		protected virtual void BuilderText() {
			_textBox.Text =
				_textBox.Text.Replace(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator, NumberGroupSeparator).
					Replace(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator, NumberDecimalSeparator);
		}


		//public TextBox TextEdit {
		//  get {
		//    EnsureChildControls();
		//    return textBox;
		//  }
		//}
		protected override void CreateClientObjectAtRender(HtmlTextWriter writer) {
			BeginScriptTag(writer);
			writer.Write("var {0}=new SpSpinEdit();window['{0}']= {0};{0}._id='{1}';", ClientName, ClientID);
			writer.Write("{0}.Init('{0}', '{1}', {2}, '{3}', '{4}', '{5}', '{6}');",
				ClientName,
				_textBox.ClientID,
			(Int32)NumberStyle,
			NumberGroupSeparator.Replace(".", @"\\.").Replace("^", @"\\^").Replace("$", @"\\$").Replace("?", @"\\?"),
			NumberGroupSeparator,
			NumberDecimalSeparator,
			NumberDecimalSeparator.Replace(".", @"\\.").Replace("^", @"\\^").Replace("$", @"\\$").Replace("?", @"\\?"));
			if (!String.IsNullOrEmpty(NotAnumberText)) {
				writer.Write("{0}.SetNotANumberText('{1}')", ClientName, NotAnumberText);
			}
			EndScriptTag(writer);
		}

		protected override void Render(HtmlTextWriter writer) {
			_textBox.Attributes["onkeyup"] = ClientName + ".KeyUp()";
			base.Render(writer);
		}
	}
}